package com.bbcare.sso.client;

import java.io.IOException;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import cn.hutool.core.collection.ListUtil;
import com.bbcare.comm.PropertiesUtils;
import org.apache.log4j.Logger;

import com.bbcare.comm.ErrorCode;
import org.springframework.util.AntPathMatcher;

public class AuthorizingFilter implements Filter {
    public static final String SESSION_ACCOUNT_KEY = "oms_account";
    private static Logger logger = Logger.getLogger(AuthorizingFilter.class);

    public static List<String> ignoreUrls= ListUtil.toList(
            "/webapi/service",
            "/switchData/",
            "/druid/",
            //泵乳通知
            "/**/webapi/service/**",
            "/**/appointment/record/detail/*",
            "/**/appointment/record/confirm/**",
            "/**/appointment/record/patientMark/**",
            "/**/message/notify/record/markRead/**",
            //备乳详情页
            "/**/milkPreparationRecord/detail/**",
            "/**/ptUserSharePhoto/historyPage/**",
            "/**/platform/**"
    );

    static AntPathMatcher antPathMatcher = new AntPathMatcher();

    /**
     * 检查url是否不需要sessionId参数。
     * @param url
     * @return
     */
    private static boolean isNoSessionUrl(final String url) {
        boolean bNoSession = false;
        final String NO_SESSION_URLS = PropertiesUtils.getProperty("gy3y_no_session_urls");
        if (null == NO_SESSION_URLS || NO_SESSION_URLS.isEmpty())   {
            return false;
        }

        for(String noSessionUrl : NO_SESSION_URLS.split(","))  {
            if (noSessionUrl.trim().equalsIgnoreCase(url)) {
                logger.debug("++++isNoSessionUrl() ["+url+"] this url doesnot need sessionId.");
                bNoSession = true;
                break;
            }
            if (noSessionUrl.endsWith("/*"))    {
                final String prefix = noSessionUrl.substring(0, noSessionUrl.length()-1);
                if (url.startsWith(prefix)) {
                    logger.debug("++++isNoSessionUrl() ["+url+"] this url doesnot need sessionId.");
                    bNoSession  = true;
                    break;
                }
            }
        }

        return bNoSession;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setHeader("Access-Control-Allow-Origin", "*"); //允许跨域访问，即platform小程序后端的H5页面来访问数据。
        // 拦截器跨域支持
        /*
         * response.setHeader("Access-Control-Allow-Origin", "*");
         * response.setHeader("Access-Control-Allow-Methods",
         * "POST, GET, OPTIONS, DELETE");
         * response.setHeader("Access-Control-Max-Age", "3600");
         * response.setHeader("Access-Control-Allow-Headers",
         * "x-requested-with");
         */
        // 静态资源不拦截
        final String url = request.getRequestURI();
        logger.info("doFilter() access url:"+url);

        boolean bCheckSession = !isNoSessionUrl(url);
        if (filter(url)) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        if (appfilter(url)) {
            // app端传入 并且传入channel值
            // String channel = request.getParameter("channel");
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        // 验证前端是否传递了sessionId，未传递则跳转登录
        String sessionId = request.getParameter("sessionId");
        if (sessionId == null && bCheckSession) {
            response.setContentType("json");
            response.setCharacterEncoding("UTF-8");
            response.getWriter().write("{\"data\":{},\"success\":false,\"code\":"
                    + ErrorCode.FOLLOWUP_EXCEPTION_TYPE_SESSION_ISNULL + ",\"msg\":\"sessionId不能为空\"}");
            // response.sendRedirect(unauthorizedUrl);
            return;
        }

        if (bCheckSession) {
            // 获取session里面账号信息，如果session没有账号信息则去redis抓
            HttpSession session = request.getSession();
            Account account = (Account) session.getAttribute(SESSION_ACCOUNT_KEY);
            if (account == null || !sessionId.equals(account.getSessionID())) {
                account = AccountService.getInstance().getAccount(sessionId);
            } else {
                AccountService.getInstance().setSessionTimeout(sessionId);
            }
            // 验证session的Id与前端传的是否一致，一致则放行，不一致跳转到登录
            if (account != null && sessionId.equals(account.getSessionID())) {
                request.getSession().setAttribute(SESSION_ACCOUNT_KEY, account);
                filterChain.doFilter(servletRequest, servletResponse);
            } else {
                logger.info("【BBcare SSO Filter fail】");
                response.setContentType("json");
                response.setCharacterEncoding("UTF-8");
                response.getWriter().write("{\"data\":{},\"success\":false,\"code\":"
                        + ErrorCode.FOLLOWUP_EXCEPTION_TYPE_SESSION_VALUEISNULL + ",\"msg\":\"session信息不存在，请退出重新登陆\"}");
                // response.sendRedirect(unauthorizedUrl);
            }
        } else {
            //不需要检查session。
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    public Boolean filter(String url) {
        if (url.indexOf(".js") != -1 || url.indexOf(".jpg") != -1 || url.indexOf(".png") != -1
                || url.indexOf(".gif") != -1 || url.indexOf(".css") != -1 || url.indexOf(".ico") != -1) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * webapi app端接口加入 不校验登陆信息
     *
     * @param url
     * @return
     */
    /*public Boolean appfilter(String url) {
        if (url.indexOf("/webapi/service") != -1
                ||url.indexOf("/switchData/") != -1
                ||url.indexOf("/zdyHisInfo/") != -1
                ||url.indexOf("/guianHisInfo/") != -1
                ||url.indexOf("/druid/")!= -1) {
            return true;
        } else {
            return false;
        }
    }*/

    public static Boolean appfilter(String url) {
        for (String ignoreUrl : ignoreUrls) {
            if(url.indexOf(ignoreUrl)!= -1 || antPathMatcher.match(ignoreUrl, url)){
                return true;
            }
        }
        return false;
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
    }

    @Override
    public void destroy() {
    }
}
